﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using JtextEpicsInterface;
using System.Collections;
using System.IO;
using System.Xml;

///*---------------------------------------------------------------------
// * Name:       SDDtoEpics    
// * Author:     Chen Lanlan
// * Version:    0.2        
// * Created:    17-06-2011
//------------------------------------------------------------------------*/

namespace JTextSdd
{
    public class SDDtoEpics
    {
        private XmlDocument doc = new XmlDocument();
        private string p = "";

        public SDDtoEpics(string path)
        {
            //DirectoryInfo dir = new DirectoryInfo(path);
            //foreach (FileSystemInfo fsi in dir.GetFileSystemInfos())
            //{
            //    if (fsi is FileInfo)
            //    {
            //        FileInfo f = (FileInfo)fsi;
            //        if (Path.GetExtension(f.FullName) == ".xml")
            //        {
            //            path = path + Path.GetFileName(f.FullName);
            //            p = path;
            //        }
            //    }

            //}

            doc.Load(path);


            servername = doc.DocumentElement.SelectSingleNode("/Config-IOC/message-based/servername").InnerText;
            isByte = Convert.ToBoolean(doc.DocumentElement.SelectSingleNode("/Config-IOC/message-based/isByte").InnerText);
            messageLen = Convert.ToInt32(doc.DocumentElement.SelectSingleNode("/Config-IOC/message-based/messageLen").InnerText);
            ending = Convert.ToByte(doc.DocumentElement.SelectSingleNode("/Config-IOC/message-based/ending").InnerText);
            scaninterval = Convert.ToDouble(doc.DocumentElement.SelectSingleNode("/Config-IOC/message-based/scaninterval").InnerText);
            scanner = doc.DocumentElement.SelectSingleNode("/Config-IOC/message-based/scanner").InnerText;
            ReplyTo = Convert.ToInt16(doc.DocumentElement.SelectSingleNode("/Config-IOC/message-based/ReplyTo").InnerText);
            DefaultScanner = doc.DocumentElement.SelectSingleNode("/Config-IOC/message-based/DefaultScanner").InnerText;
            Spliter = doc.DocumentElement.SelectSingleNode("/Config-IOC/message-based/Spliter").InnerText;


            IocName = Convert.ToString(doc.DocumentElement.SelectSingleNode("/Config-IOC/register-based/IocName").InnerText);
            IocInterval = Convert.ToDouble(doc.SelectSingleNode("/Config-IOC/register-based/IocInterval").InnerText);
        }
        ~SDDtoEpics()
        {
            doc.Save(p);
        }


        #region var

        public string servername;
        public bool isByte;
        public int messageLen;
        public byte ending;
        public double scaninterval;
        public string scanner;
        public int ReplyTo;
        public string DefaultScanner;         //Added by Version 0.2
        public string Spliter;

        public double IocInterval;
        public string IocName;

        #endregion

        #region getRegisterPV

        private Record_prop getRecord(string name)
        {
            Record_prop record = new Record_prop();
            XmlNodeList nodes = doc.DocumentElement.SelectNodes("/Config-IOC/register-based/pvs/pv");

            foreach (XmlNode node in nodes)
            {
                if (node.FirstChild.InnerText == name)
                {
                    record.pvName = name;
                    foreach (XmlNode cnode in node.ChildNodes)
                    {
                        #region record-prop
                        switch (cnode.Name)
                        {
                            case "DESC":
                                record.DESC = cnode.FirstChild.InnerText;
                                break;
                            case "EGU":
                                record.EGU = cnode.FirstChild.InnerText;
                                break;
                            case "HIHI":
                                record.HIHI = Convert.ToDouble(cnode.FirstChild.InnerText);
                                break;
                            case "HIGH":
                                record.HIGH = Convert.ToDouble(cnode.FirstChild.InnerText);
                                break;
                            case "LOW":
                                record.LOW = Convert.ToDouble(cnode.FirstChild.InnerText);
                                break;
                            case "LOLO":
                                record.LOLO = Convert.ToDouble(cnode.FirstChild.InnerText);
                                break;
                            case "SCANINTERVAL":
                                record.SCANINTERVAL = Convert.ToInt32(cnode.FirstChild.InnerText);
                                break;
                            case "Drv_path":
                                record.Drv_path = cnode.FirstChild.InnerText;
                                break;
                            case "Drv_name":
                                record.Drv_name = Convert.ToString(cnode.FirstChild.InnerText);
                                break;
                            case "isInput":
                                record.isInput = Convert.ToBoolean(cnode.FirstChild.InnerText);
                                break;
                            case "eXtension":
                                record.eXtension = (object)cnode.FirstChild.InnerText;
                                break;
                            case "DataClass":
                                record.DataClass = Convert.ToInt32(cnode.FirstChild.InnerText);
                                break;
                            case "DataType":
                                record.DataType = Convert.ToString(cnode.FirstChild.InnerText);
                                break;
                            case "ArrayLen":
                                record.ArrayLen = Convert.ToInt32(cnode.FirstChild.InnerText);
                                break;
                            case "multilple":
                                record.multilple = Convert.ToDouble(cnode.FirstChild.InnerText);
                                break;
                            case "offset":
                                record.offset = Convert.ToDouble(cnode.FirstChild.InnerText);
                                break;
                            case "HighDisplayLimit":
                                record.HighDisplayLimit = Convert.ToDouble(cnode.FirstChild.InnerText);
                                break;
                            case "LowDisplayLimit":
                                record.LowDisplayLimit = Convert.ToDouble(cnode.FirstChild.InnerText);
                                break;
                            case "DeviceName":
                                record.DeviceName = Convert.ToString(cnode.FirstChild.InnerText);
                                break;
                            case "DeviceProperty":
                                record.DeviceProperty = Convert.ToString(cnode.FirstChild.InnerText);
                                break;
                            case "DeviceDtatType":
                                record.DeviceDtatType = Convert.ToString(cnode.FirstChild.InnerText);
                                break;
                            case "PlugIns":
                                record.PlugIns = Convert.ToString(cnode.FirstChild.InnerText).Split(new char[] { ';' });
                                break;
                        }
                        #endregion
                    }
                }
            }

            return record;
        }

        private ArrayList getAllPvNames()
        {
            XmlNodeList list = doc.DocumentElement.SelectNodes("/Config-IOC/register-based/pvs/pv");
            ArrayList ar = new ArrayList();
            foreach (XmlNode node in list)
            {
                ar.Add(node.FirstChild.InnerText);
            }
            return ar;

        }

        public Record_prop[] getAllRecord()
        {
            ArrayList pvNames = getAllPvNames();
            ArrayList records = new ArrayList();

            foreach (string name in pvNames)
            {
                records.Add(getRecord(name));
            }

            Record_prop[] Records = (Record_prop[])records.ToArray(typeof(Record_prop));
            return Records;
        }

        #endregion


        #region getMessagePV

        public MessageProp[] getAllMessageprop()
        {
            ArrayList arr = new ArrayList();


            
            XmlNodeList nodes = doc.DocumentElement.SelectNodes("/Config-IOC/message-based/pvs/pv");
            foreach (XmlNode node in nodes)
            {
                MessageProp mes = new MessageProp();
                foreach (XmlNode cnode in node.ChildNodes)
                {

                    switch (cnode.Name)
                    {
                        case "PvName":
                            mes.pvName = Convert.ToString(cnode.FirstChild.InnerText);
                            break;
                        case "isByte":
                            mes.isByte = Convert.ToBoolean(cnode.FirstChild.InnerText);
                            break;
                        case "Position":
                            mes.Position = Convert.ToInt32(cnode.FirstChild.InnerText);
                            break;
                        case "offset":
                            mes.offset = Convert.ToInt32(cnode.FirstChild.InnerText);
                            break;
                        case "shift":
                            mes.shift = Convert.ToInt32(cnode.FirstChild.InnerText);
                            break;
                        case "isBit":
                            mes.isBit = Convert.ToInt16(cnode.FirstChild.InnerText);
                            break;
                        case "VAL":
                            mes.VAL = (object)cnode.FirstChild.InnerText;
                            break;
                        case "DeviceName":                                                         //Added by Version 0.2
                            mes.DeviceName = Convert.ToString(cnode.FirstChild.InnerText);
                            break;
                        case "DeviceProperty":                                                   //Added by Version 0.2
                            mes.DeviceProperty = Convert.ToString(cnode.FirstChild.InnerText);
                            break;
                        case "DeviceDtatType":                                                 //Added by Version 0.2
                            mes.DeviceDtatType = Convert.ToString(cnode.FirstChild.InnerText);
                            break;

                    }

                }
                arr.Add(mes);
            }

            MessageProp[] m = (MessageProp[])arr.ToArray(typeof(MessageProp));
            return m;


        }
        #endregion


        private string[] toGetSomeElement(string nodePath, int count)
        {
            string[] str = new string[count];
            int i = 0;
            XmlNode node = doc.DocumentElement.SelectSingleNode(nodePath);
            XmlNodeList nodes = node.ChildNodes;
            foreach (XmlNode n in nodes)
            {
                str[i] = n.FirstChild.InnerText;
                i++;
            }
            return str;

        }

        public ArrayList[] DevicesRegister()
        {
            XmlNodeList nodes = doc.DocumentElement.SelectNodes("/Config-IOC/register-based/Devices/Device");
            ArrayList arr = new ArrayList();
            foreach (XmlNode node in nodes)
            {
                ArrayList d = new ArrayList();
                foreach (XmlNode cnode in node.ChildNodes)
                {
                    d.Add(cnode.FirstChild.InnerText);
                }
                arr.Add(d);
            }
            ArrayList[] a = (ArrayList[])arr.ToArray(typeof(ArrayList));

            return a;
        }
        public ArrayList DriversRegister()
        {
            ArrayList ab = new ArrayList();
            XmlNodeList nodes = doc.SelectNodes("/Config-IOC/register-based/drivers/drv");
            foreach (XmlNode node in nodes)
            {
                ab.Add(node.FirstChild.FirstChild.InnerText);
            }
            return ab;
        }

        //return a list by this ordor[DriverFlie,DriverName,DriverPath,timeout,timeoutlimit];
        //Added by Version 0.2
        public string[] DriverMessage()
        {
            string[] str = toGetSomeElement("/Config-IOC/message-based/driver", 5);
            return str;
        }


        //return a list by this ordor[DeviceName,DeviceType];
        //Added by Version 0.2
        public string[] DeviceMessage()
        {
            string[] str = toGetSomeElement("/Config-IOC/message-based/Device", 2);
            return str;
        }

    }
}
